<template>
  <div>
    <high-search :list="searchList" title="角色筛选查询" @searchFn="searchFn" />
    <custom-table
      title="角色列表"
      style="margin-top: 10px"
      :column="column"
      :tableConfig="tableConfig"
      @row-dblclick="rowDblClick"
      @current-change="currentChange"
      @checkBox-change="checkBoxChange"
      @page-change="pageChange"
    >
      <template #customTools>
        <el-col :span="24">
          <el-button type="primary" @click="addRole">新增角色</el-button>
        </el-col>
      </template>
      <template #actionColumn1="scope">
        <el-button type="primary" @click="updateFn(scope)">修改</el-button>
        <el-button type="danger" @click="deleteFn(scope)">删除</el-button>
        <el-button type="primary" @click="roleAuthFn(scope, 'true')"
          >授权</el-button
        >
        <el-button type="danger" @click="roleAuthFn(scope, 'false')"
          >取消授权</el-button
        >
      </template>
    </custom-table>
    <el-dialog
      @close="closeFn"
      center
      width="500px"
      :title="title1"
      :close-on-click-modal="false"
      :visible.sync="addDialog"
    >
      <el-form ref="formItem" :model="formItem" label-width="100px"
        ><el-row :gutter="10">
          <el-col :span="24" v-for="(item, i) in list" :key="i"
            ><el-form-item
              :prop="item.prop"
              :rules="item.rules"
              :label="item.label + ':'"
            >
              <el-input
                :type="item.type || ''"
                :placeholder="item.placeholder"
                v-model="formItem[item.prop]"
              ></el-input></el-form-item></el-col></el-row
      ></el-form>
      <template #footer>
        <div>
          <el-button type="primary" @click="confirm">确认</el-button>
          <el-button @click="closeFn">取消</el-button>
        </div>
      </template>
    </el-dialog>
    <el-dialog
      @close="cancelFn1"
      center
      width="900px"
      :title="title"
      :close-on-click-modal="false"
      :visible.sync="roleAuth"
    >
      <TreeTable
        expand-key="menuId"
        ref="treeTable"
        selectable
        select-type="checkbox"
        :expand-type="false"
        tree-type
        border
        :data="categoriesdata"
        :columns="columns"
      >
        <template slot="icon" slot-scope="scope">
          <div style="display: flex; justify-content: center">
            <i :class="scope.row.icon" style="font-size: 16px"></i>
          </div>
        </template>
      </TreeTable>
      <template #footer>
        <div>
          <el-button type="primary" @click="confirm1">确认</el-button>
          <el-button @click="cancelFn1">取消</el-button>
        </div>
      </template>
    </el-dialog>
  </div>
</template>

<script>
import {
  rolelist,
  addRole,
  addAuth,
  selectAuth,
  cancelAuth,
  updateRole,
  deleteRole,
} from "_my/api/admin";
import { getParentId, getChildNode } from "_my_utils/tools";

import TreeTable from "tree-table-vue";
export default {
  name: "roleConfig",
  components: { TreeTable },
  data() {
    return {
      title: "",
      title1: "",
      categoriesdata: [],
      roleAuth: false,
      formItem: {},
      searchList: [
        {
          label: "角色编码",
          prop: "roleCode",
          type: "input",
          placeholder: "请输入角色编码",
        },
        {
          label: "角色名称",
          prop: "roleName",
          type: "input",
          placeholder: "请输入角色名称",
        },
      ],
      list: [
        {
          label: "角色编码",
          prop: "roleCode",
          placeholder: "请输入角色编码",
          rules: [
            { required: true, message: "角色编码不能为空", trigger: "blur" },
          ],
        },
        {
          label: "角色名称",
          prop: "roleName",
          placeholder: "请输入角色名称",
          rules: [
            { required: true, message: "角色名称不能为空", trigger: "blur" },
          ],
        },
        {
          label: "角色描述",
          prop: "roleInfo",
          placeholder: "请输入角色描述",
        },
      ],
      addDialog: false,
      column: [
        {
          prop: "roleCode",
          label: "角色编码",
          width: 200,
        },
        {
          prop: "roleName",
          label: "角色名称",
          width: 200,
        },

        {
          prop: "roleInfo",
          label: "角色描述",
        },
      ],
      columns: [
        { title: "菜单编码", key: "menuId", width: "210" },
        {
          headerAlign: "center",
          align: "center",
          title: "图标",
          key: "icon",
          width: "60",
          type: "template",
          template: "icon",
        },
        {
          headerAlign: "center",
          align: "center",
          title: "菜单名称",
          key: "menuName",
          width: "240",
        },
        {
          title: "菜单路径",
          key: "menuPath",
          width: "280",
        },
      ],
      tableConfig: {
        total: 0,
        useIndex: false,
        useMultiSelect: false,
        pageSize: 10,
        rowKey: "rid",
        pageNo: 1,
        showPagination: true,
        data: [],
        actionColumns: [
          {
            label: "操作",
            slotName: "actionColumn1",
            width: 320,
          },
        ],
      },
      select: {},
      search: {},
    };
  },
  methods: {
    deleteFn(scope) {
      this.$confirm("确定要删除该条数据吗？", "警告", {
        confirmButtonText: "确定",
        cancelButtonText: "取消",
        type: "warning",
      })
        .then(() => {
          deleteRole({ rid: scope.row.rid }).then((res) => {
            if (res.data.code === 201) {
              this.getTableList();
            }
          });
        })
        .catch(() => {
          this.$message({
            type: "info",
            message: "已取消删除",
          });
        });
    },
    searchFn(params) {
      this.search = params;
      this.getTableList();
    },
    resetFn() {
      this.search = {};
    },
    cancelFn1() {
      this.roleAuth = false;
    },
    roleAuthFn(scope, status) {
      this.title = status === "true" ? "菜单授权" : "取消授权";
      this.select = scope.row;
      const data = {
        rid: this.select.rid,
        status,
      };
      selectAuth(data).then((res) => {
        this.categoriesdata = res.data;
      });
      this.roleAuth = true;
    },
    confirm1() {
      let arr = this.$refs.treeTable.getCheckedProp("menuPath").map((item) => {
        return getParentId(this.categoriesdata, item, "menuPath").map(
          (item) => item.menuId
        );
      });
      arr = [...new Set(arr.flat(Infinity))];
      if (arr.length === 0) {
        return this.$message({
          type: "error",
          message: "请选择需要授权或取消授权的菜单",
        });
      }
      if (this.title === "菜单授权") {
        const menuId = arr.map((item) => {
          const obj = {};
          obj.menuId = item;
          obj.allselect = getChildNode(this.categoriesdata, item, [])
            .every((item) => arr.includes(item))
            .toString();
          return obj;
        });
        const data = {
          menuId,
          rid: this.select.rid,
        };
        addAuth(data).then((res) => {
          if (res.data.code === 201) {
            this.roleAuth = false;
          }
        });
      } else {
        const menuId = arr.map((item) => {
          const obj = {};
          obj.menuId = item;
          obj.allselect = getChildNode(this.categoriesdata, item, [])
            .every((item) => arr.includes(item))
            .toString();
          obj.status = obj.allselect === "true" ? 0 : 1;
          return obj;
        });
        const data = {
          menuId,
          rid: this.select.rid,
        };
        cancelAuth(data).then((res) => {
          if (res.data.code === 201) {
            this.roleAuth = false;
          }
        });
      }
    },
    confirm() {
      this.$refs.formItem.validate((res) => {
        if (res) {
          if (this.title1 === "新增角色") {
            addRole(this.formItem).then((res) => {
              if (res.data.code === 201) {
                this.closeFn();
                this.getTableList();
              }
            });
          } else {
            updateRole(this.formItem).then((res) => {
              if (res.data.code === 201) {
                this.closeFn();
                this.getTableList();
              }
            });
          }
        } else {
          this.$message({
            type: "error",
            message: "请完成必填项",
          });
        }
      });
    },
    closeFn() {
      this.addDialog = false;
      this.formItem = {};
      this.$refs.formItem.resetFields();
    },
    rowDblClick(row, column, event) {
      console.log(row, column, event);
    },
    checkBoxChange(selection, row) {
      console.log(selection, row);
    },
    currentChange(current) {
      this.tableConfig.pageNo = current;
      this.getTableList();
    },
    pageChange(pageSize) {
      this.tableConfig.pageSize = pageSize;
      this.tableConfig.pageNo = 1;
      this.getTableList();
    },
    getTableList() {
      const data = Object.assign({}, this.search);
      data.pageSize = this.tableConfig.pageSize;
      data.pageNo = this.tableConfig.pageNo;
      rolelist(data).then((res) => {
        if (res.data.code === 200) {
          this.tableConfig.data = res.data.data.list;
          this.tableConfig.total = res.data.data.total;
        }
      });
    },
    addRole() {
      this.title1 = "新增角色";
      this.addDialog = true;
    },
    updateFn(scope) {
      this.formItem = JSON.parse(JSON.stringify(scope.row));
      this.title1 = "修改角色";
      this.addDialog = true;
    },
  },
  mounted() {
    this.getTableList();
  },
};
</script>

<style lang="less" scoped>
.user {
  user-select: none;
  user-zoom: 0;
  -webkit-user-drag: none;
}
:deep(.zk-table__cell-inner) {
  padding: 2px 12px;
}
:deep(.zk-table__body-row) {
  height: 28px;
  user-select: none;
}
:deep(.zk-table__header-row) {
  background: #4d76a2;
  user-select: none;
  color: #fff;
}
:deep(.zk-checkbox--indeterminate .zk-checkbox__inner),
:deep(.zk-checkbox--checked .zk-checkbox__inner) {
  background: #4d76a2;
  border-color: #4d76a2;
}
.search :deep(.el-form-item) {
  margin-bottom: 10px;
}
</style>
